home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Medal Software 2
/
Gold Medal Software Volume 2 (Gold Medal) (1994).iso
/
prog
/
asm_n_z.arj
/
NEWXDIR.ASM
< prev
next >
Wrap
Assembly Source File
|
1987-04-07
|
43KB
|
841 lines
;XDIR.COM for the IBM Personal Computer - 1986 by Jeff Prosise
code segment para public 'code'
assume cs:code
org 100h
begin: jmp initialize ;goto initialization code
;
copyright db 'Copyright 1986 Ziff-Davis Publishing Co.',1Ah
global db '\*.*',0 ;global directory filespec
dos_segment dw ? ;DOS segment
busy_flag dw ? ;offset of DOS BUSY_FLAG
program_status db 0 ;XDIR processing status
flag_13h db 0 ;status of interrupt 13h
request_flag db 0 ;status of processing request
adapter db 2 ;0 = MDA, 1 = CGA, 2 = EGA
video_segment dw 0B800h ;video segment address
video_page db ? ;current video page
border_attr db 4Fh ;window border attribute
text_attr db 0Fh ;window text attribute
video_address dw ? ;window start address
cursor_mode dw ? ;cursor shape
cursor_pos dw ? ;cursor position
maxlen db ? ;maximum input string length
max_page db ? ;number of highest directory page
dir_page db ? ;current directory page
end_flag db ? ;status of text write routines
error_flag db ? ;critical error status
default_cursor dw 0607h ;default cursor shape (color)
addr_6845 dw ? ;CRT Controller base address
search_attr dw 0 ;file search attribute
;
path dw 0 ;pointer to pathname buffer
dta dw 64 ;pointer to Disk Transfer Area
screen_buffer dw offset initialize ;pointer to screen buffer
text_buffer dw offset initialize+1536 ;pointer to filename buffer
;
keyboard_int label dword ;old interrupt 9 vector
old9h dw 2 dup (?)
timer_int label dword ;old interrupt 1Ch vector
old1ch dw 2 dup (?)
bdisk_int label dword ;old interrupt 13h vector
old13h dw 2 dup (?)
bp_int label dword ;old interrupt 28h vector
old28h dw 2 dup (?)
;
old_dta_segment dw ? ;old DTA segment address
old_dta_offset dw ? ;old DTA offset address
old24h_segment dw ? ;old interrupt 24h routine segment
old24h_offset dw ? ;old interrupt 24h routine offset
enable_values db 2Ch,28h,2Dh,29h ;values to enable CGA output
db 2Ah,2Eh,1Eh
errtext db 'No Files Found',0
;
;------------------------------------------------------------------------------
;Execution comes here thru interrupt 9 every time a key is pressed or released.
;------------------------------------------------------------------------------
keyboard proc near
sti ;set interrupt enable flag
push ax ;save AX
in al,60h ;get scan code from keyboard
cmp al,52 ;was the '.' key pressed?
jne kb2 ;no, then exit to normal handler
mov ah,2 ;check shift key status
int 16h
test al,8 ;is the Alt key pressed?
je kb2 ;no, then exit
call kb_reset ;reset keyboard, issue EOI
pop ax ;restore AX
cmp program_status,0 ;XDIR routine already active?
jne kb1 ;yes, then don't set request flag
mov request_flag,1 ;set request flag
kb1: iret ;end interrupt routine
kb2: pop ax ;restore AX
jmp keyboard_int ;goto original keyboard routine
keyboard endp
;
;------------------------------------------------------------------------------
;Interrupt 1Ch handling routine.
;This procedure will now be used to handle int 8 instead of int 1c
;------------------------------------------------------------------------------
timer proc near
pushf ;call original routine
call timer_int
cmp request_flag,0 ;request flag set?
je timer1 ;no, then exit
push es ;save ES and DI
push di
mov es,dos_segment ;get DOS segment in ES
mov di,busy_flag ;address of DOS BUSY_FLAG in DI
cmp byte ptr es:[di],0 ;DOS service currently active?
pop di ;clean up the stack
pop es
jne timer1 ;yes, then we must wait
cmp flag_13h,0 ;BIOS disk service active?
jne timer1 ;yes, then don't interrupt it
test_8259_status:
push AX ;Save altered registers
push DX
mov DX,20h ;Port address of 8259 OCW3
mov AL,03 ;Set the In-Service Reg. read
;bits RR=1 and RIS=1
out DX,AL ;Tell 8259 to send ISR on next read
jmp short get_mask ;This causes a 7 clock delay period
;on the AT to allow time for the 8259
;to setup the ISR status for us
get_mask:
in AL,DX ;Get the ISR
or AL,AL ;Set zero flag if no interrupts are
;being serviced
pop DX ;Restore the altered registers
pop AX
jnz timer1 ;A hard interrupt is in progress
mov request_flag,0 ;reset request flag
call directory ;invoke directory routine
timer1: iret ;done - exit
timer endp
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;Interrupt 13h handling routine.
;------------------------------------------------------------------------------
bdisk proc far
inc flag_13h ;Set the busy flag
pushf ;Simulate an interrupt call to the
call bdisk_int ;original disk interrupt routine
pushf ;Save returned flags from disk interrupt
dec flag_13h ;Clear the busy flag
popf ;Restore disk I/O status flags
ret 2 ;Far return and discard flags on the stack
bdisk endp
;
;------------------------------------------------------------------------------
;Interrupt 28h handling routine.
;------------------------------------------------------------------------------
backproc proc near
pushf ;call original routine
call bp_int
cmp request_flag,0 ;request flag clear?
je bp1 ;yes, then exit
mov request_flag,0 ;clear request flag
call directory ;execute directory routine
bp1: iret ;done - exit
backproc endp
;
;------------------------------------------------------------------------------
;Interrupt 24h handling routine.
;------------------------------------------------------------------------------
ioerr proc near
sti ;restore interrupts
mov error_flag,1 ;set external error flag
mov al,0 ;tell DOS to ignore the error
iret ;give control back to DOS
ioerr endp
;
;------------------------------------------------------------------------------
;DIRECTORY is called by other routines to pop up and control the window.
;------------------------------------------------------------------------------
directory proc near
mov program_status,1 ;set program active flag
sti ;enable interrupts
push ax ;save registers
push bx
push cx
push dx
push si
push di
push ds
push es
push cs ;set DS to the code segment
pop ds
assume ds:code
push cs ;set ES to the code segment
pop es
;
;Make sure the current video mode is a text mode.
;
mov ah,15 ;get video mode and page
int 10h
cmp al,2 ;mode 2?
je dir1 ;yes, then continue
cmp al,3 ;mode 3?
je dir1 ;yes, then continue
cmp al,7 ;mode 7?
je dir1 ;yes, then continue
exit: mov program_status,0 ;clear status flag
pop es ;restore registers and exit
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
;
;Save video parameters that must be used now or restored later.
;
dir1: mov video_page,bh ;save current video page
mov ah,3 ;get cursor mode
int 10h
mov cursor_mode,cx ;save it
call cursor_address ;get cursor address from CRTC
mov cursor_pos,ax ;save it
cld ;clear DF for string operations
;
;Save the screen contents and open the directory window.
;
cmp adapter,1 ;disable video if CGA installed
jne dir2
call disable_cga
dir2: call save_screen ;save memory to be overwritten
call open_window ;draw window to the display
cmp adapter,1 ;re-enable CGA video
jne dir3
call enable_cga
;
;Set the DTA and interrupt 24h vector to areas inside XDIR. Then get a
;directory path string from the keyboard.
;
dir3: call ioset ;set DTA and 24h vector
dir4: mov di,path ;point DI to directory path buffer
mov dx,020Ah ;specify input line location
mov cl,59 ;specify max length of 59
call readln ;get path string from keyboard
cmp al,27 ;was ESC pressed?
jne dir5 ;no, then continue
jmp escape ;ESC was pressed - exit
dir5: push cx ;save character count
mov ah,1 ;hide the cursor
mov ch,20h
int 10h
pop cx ;retrieve count
mov dx,offset global+1 ;point DX to '*.*' text
or cl,cl ;any characters entered?
je dir7 ;yes, then skip ahead
cmp byte ptr [di-1],'\' ;is last character a backslash?
jne dir6 ;no, then append backslash to path
dec di ;decrement path string pointer
dir6: lea si,global ;append '\*.*' text to path
mov cx,5
rep movsb
mov dx,path ;point DX to path string
;
;Read filename information from the specified directory.
;
dir7: call get_dir ;read directory information
mov dir_page,0 ;initialize page number
or cx,cx ;any files found?
jne dir9 ;yes, then continue
;
;No files were found - print message and return to input loop.
;
mov dx,0721h ;set cursor position
lea si,errtext ;point SI to error message
call write_string ;write error message
call getkey ;wait for a keypress
call clear_input_line ;clear input line
call clear_window ;then clear the window
jmp dir4 ;loop back for another try
;
;One or more files were found. Display them and look for keystrokes.
;
dir9: call write_dir ;write one directory page
dir10: call getkey ;wait for a keypress
cmp al,0 ;extended code entered?
je dir11 ;yes, then branch to handler
cmp al,27 ;ESC pressed?
jne dir10 ;no, then ignore keypress
call clear_input_line ;clear window and loop back
call clear_window
jmp dir4
dir11: cmp ah,81 ;PgDn pressed?
jne dir12 ;no, then continue testing
mov al,dir_page ;last page displayed?
cmp al,max_page
je dir10 ;yes, then ignore keypress
inc dir_page ;advance page number
call clear_window ;clear window
jmp dir9 ;go back and display new page
dir12: cmp ah,73 ;PgUp pressed?
jne dir10 ;no, then ignore keypress
cmp dir_page,0 ;first page displayed?
je dir10 ;yes, then ignore keypress
dec dir_page ;update page indicator
call clear_window ;clear window
jmp dir9 ;loop back
;
;Reset the 24h vector and DTA address, close the window, and exit.
;
escape: call ioreset ;restore DTA and 24h vector
cmp adapter,1 ;disable CGA video
jne esc1
call disable_cga
esc1: call restore_screen ;restore screen contents
cmp adapter,1 ;re-enable CGA video
jne esc2
call enable_cga
esc2: mov ah,2 ;set cursor position
mov bh,video_page
mov dx,cursor_pos
int 10h
mov ah,1 ;then unblank the cursor
mov cx,cursor_mode
int 10h
jmp exit ;exit
directory endp
;
;------------------------------------------------------------------------------
;SAVE_SCREEN saves the contents of the screen that underlie the window.
;------------------------------------------------------------------------------
save_screen proc near
mov dx,0208h ;first window row and column
mov bl,video_page ;retrieve active video page
xor bh,bh ;byte to word in BX
call video_offset ;determine video memory offset
mov video_address,di ;save offset address
mov si,di ;transfer it to SI
push ds ;save DS
mov ds,video_segment ;then set it to the video segment
assume ds:nothing
mov di,screen_buffer ;point DI to storage buffer
mov cx,12 ;12 lines to save
save1: push cx ;save line count
mov cx,64 ;64 characters per line
rep movsw ;transfer one line to storage
pop cx ;retrieve line count
add si,32 ;point SI to next video line
loop save1 ;loop until all lines are saved
pop ds ;restore DS
assume ds:code
ret ;exit
save_screen endp
;
;------------------------------------------------------------------------------
;RESTORE_SCREEN restores the saved contents of video memory.
;------------------------------------------------------------------------------
restore_screen proc near
push es ;save ES register value
mov di,video_address ;point DI to starting video offset
mov es,video_segment ;point ES to video memory
mov si,screen_buffer ;point SI to storage buffer
mov cx,12 ;12 lines to restore
restore1: push cx ;save line count
mov cx,64 ;64 characters per line
rep movsw ;restore one line
pop cx ;retrieve line count
add di,32 ;set DI to next video line
loop restore1 ;loop until done
pop es ;restore ES
ret
restore_screen endp
;
;------------------------------------------------------------------------------
;VIDEO_OFFSET calculates the offset address in video memory that corresponds
;to the indicated row, column, and video page.
;Entry: DH,DL - row, column | Exit: DI - offset
; BX - video page |
;------------------------------------------------------------------------------
video_offset proc near
mov al,160 ;row * 160
mul dh
shl dl,1 ;column * 2
xor dh,dh ;byte to word in DX
add ax,dx ;add the results
mov di,ax ;save result in DI
mov ax,1000h ;length of one video page
mul bx ;page * 1000h
add di,ax ;add result to DI
ret
video_offset endp
;
;------------------------------------------------------------------------------
;DISABLE_CGA and ENABLE_CGA disable and enable CGA video output.
;------------------------------------------------------------------------------
disable_cga proc near
mov dx,3DAh ;address of Status Register
disable1: in al,dx ;get status
test al,8 ;vertical retrace active?
je disable1 ;no, then wait
sub dx,2 ;MSR address in DX
mov al,25h ;value to disable video
out dx,al ;disable video output
ret
disable_cga endp
;
enable_cga proc near
mov ah,15 ;get video mode
int 10h
lea bx,enable_values ;get value to enable display
xlat ;value in AL
mov dx,3D8h ;MSR address
out dx,al ;enable video output
ret
enable_cga endp
;
;------------------------------------------------------------------------------
;KB_RESET resets the keyboard and issues an EOI to the 8259 PIC.
;------------------------------------------------------------------------------
kb_reset proc near
in al,61h ;get current control value
mov ah,al ;save it in AH
or al,80h ;set the high bit
out 61h,al ;send it to the control port
mov al,ah ;recover original value
out 61h,al ;send it out
cli ;suspend interrupts
mov al,20h ;load EOI value
out 20h,al ;send it to the 8259
sti ;restore interrupts
ret
kb_reset endp
;
;------------------------------------------------------------------------------
;SHOW_CURSOR sets the cursor to its default state.
;------------------------------------------------------------------------------
show_cursor proc near
mov ah,1 ;interrupt 10h service 1
mov cx,default_cursor ;set scan line definition
int 10h ;set cursor shape
ret
show_cursor endp
;
;------------------------------------------------------------------------------
;CURSOR_ADDRESS reads the current cursor position from the video controller.
;------------------------------------------------------------------------------
cursor_address proc near
mov dx,addr_6845 ;get CRTC Address Register port
mov al,14 ;OUT register number
out dx,al
inc dx ;point DX to Data Register
in al,dx ;read high byte of cursor address
mov ah,al ;save it in AH
dec dx ;point DX back to Address Register
mov al,15 ;OUT next register number
out dx,al
inc dx ;point DX to Data Register
in al,dx ;read low byte of address
and ax,07FFh ;strip 'page' bits from address
mov bl,80 ;then divide by 80
div bl
xchg ah,al ;reverse bytes for proper form
ret
cursor_address endp
;
;------------------------------------------------------------------------------
;GETKEY waits for a keypress and returns the keycode in AX.
;Exit: AX - keycode
;------------------------------------------------------------------------------
getkey proc near
mov ah,1 ;check keyboard buffer
int 16h
jne getkey1 ;jump if buffer contains a keycode
int 28h ;no key pressed - issue int 28h
jmp getkey ;loop back to try again
getkey1: mov ah,0 ;get keycode from buffer
int 16h
ret ;exit with keycode in AX
getkey endp
;
;------------------------------------------------------------------------------
;OPEN_WINDOW writes the blank directory window to display memory.
;------------------------------------------------------------------------------
open_window proc near
push es ;save ES
mov es,video_segment ;set ES:DI to video memory
mov di,video_address
mov al,218 ;write first character
mov ah,border_attr
stosw
mov cx,62 ;then do the next 62
mov al,32
rep stosw
mov al,191 ;finish the first line
stosw
add di,32 ;set DI to start of next line
mov cx,10 ;10 lines to do
open1: push cx ;save line counter
mov al,179 ;write first character on line
mov ah,border_attr
push ax ;save character/attribute pair
stosw ;write them to video memory
mov cx,62 ;write next 62 characters
mov al,32
mov ah,text_attr
rep stosw
pop ax ;retrieve saved word for final char
stosw ;finish the line
add di,32 ;set DI to start of next line
pop cx ;retrieve line counter
loop open1 ;loop until 10 lines are done
mov al,192 ;first character of last line
stosw
mov cx,62 ;write the next 62 characters
mov al,196
rep stosw
mov al,217 ;finish the last line
stosw
pop es ;restore ES
ret
open_window endp
;
;------------------------------------------------------------------------------
;READLN accepts input of a string entered from the keyboard.
;Entry: ES:DI - buffer address | Exit: CL - string length
; DH,DL - cursor start position |
; CL - max length accepted |
;------------------------------------------------------------------------------
readln proc near
mov maxlen,cl ;save max length
mov ah,2 ;set cursor to start position
mov bh,video_page
int 10h
call show_cursor ;make sure cursor is visible
xor cl,cl ;initialize counter
read1: call getkey ;get a character
cmp al,13 ;ENTER key?
je read_exit ;yes, then exit
cmp al,27 ;ESC key?
je read_exit ;yes, then exit
cmp al,8 ;backspace key?
je backspace ;yes, then do backspace function
cmp al,32 ;ASCII 32 or greater?
jb read1 ;no, then ignore it
cmp cl,maxlen ;room for another entry?
je read1 ;no, then ignore it
push ax ;save character just entered
push cx ;save character count
mov ah,10 ;print the character
mov cx,1
int 10h
inc dl ;advance the cursor
mov ah,2
int 10h
pop cx ;retrieve count
pop ax ;retrieve character
stosb ;deposit entry in buffer
inc cl ;update count
jmp read1 ;go back for more
backspace: or cl,cl ;any characters to delete?
je read1 ;no, then ignore keystroke
push cx ;save count
dec dl ;move cursor back one space
mov ah,2
int 10h
mov ah,10 ;print a space character
mov al,32
mov cx,1
int 10h
pop cx ;retrieve count
dec cl ;decrement it
dec di ;decrement buffer pointer
jmp read1 ;go back for more
read_exit: ret ;exit
readln endp
;
;------------------------------------------------------------------------------
;IOSET saves the current DTA address and interrupt 24h vector, then replaces
;them with pointers to XDIR routines. IORESET restores the original values.
;------------------------------------------------------------------------------
ioset proc near
push es ;save ES
mov ah,2Fh ;get current DTA address
int 21h
mov old_dta_segment,es ;save it
mov old_dta_offset,bx
mov ah,1Ah ;set new DTA address
mov dx,dta
int 21h
mov ah,35h ;get interrupt 24h vector
mov al,24h
int 21h
mov old24h_segment,es ;save it
mov old24h_offset,bx
mov ah,25h ;then set it to IOERR routine
lea dx,ioerr
int 21h
pop es ;restore ES
ret
ioset endp
;
ioreset proc near
mov ah,25h ;restore interrupt 24h vector
mov al,24h
mov dx,old24h_offset
push ds
assume ds:nothing
mov ds,old24h_segment
int 21h
mov ah,1Ah ;restore original DTA address
mov dx,old_dta_offset
mov ds,old_dta_segment
int 21h
pop ds
assume ds:code
ret
ioreset endp
;
;------------------------------------------------------------------------------
;GET_DIR reads the specified directory and stores the ASCIIZ filename text.
;Entry: DS:DX - pathname | Exit: CX - number of files
;------------------------------------------------------------------------------
get_dir proc near
mov error_flag,0 ;initialize critical error flag
mov ah,4Eh ;find first filename
mov cx,search_attr ;set search attribute
int 21h ;initiate file search
mov cx,0 ;zero CX in case no files found
jc getdir4 ;done if no files found
cmp error_flag,0 ;critical error flag clear?
jne getdir4 ;no, then exit immediately
inc cx ;initialize file count
mov di,text_buffer ;set buffer address
call copy_filename ;copy filename to buffer
getdir1: mov ah,4Fh ;continue file search
int 21h
jc getdir2 ;done if nothing found
cmp error_flag,0 ;did a critical error occur?
jne getdir2 ;yes, then exit
call copy_filename ;copy next filename
inc cx ;update counter
cmp cx,360 ;buffer full?
jne getdir1 ;no, go back for more
getdir2: sub di,13 ;go back to start of last filename
getdir3: inc di ;point DI to next byte
cmp byte ptr es:[di],0 ;is this a zero byte?
jne getdir3 ;no, then advance to next byte
dec byte ptr es:[di] ;mark end of text with a 255
mov ax,cx ;calculate number of pages
dec ax
mov bl,40
div bl
mov max_page,al ;save highest page number
getdir4: ret
get_dir endp
;
;------------------------------------------------------------------------------
;COPY_FILENAME copies an ASCIIZ filename from the DTA to the indicated address.
;Entry: ES:DI - destination address
;------------------------------------------------------------------------------
copy_filename proc near
mov si,dta ;get DTA address
add si,30 ;point SI to start of filename
push cx ;save CX
mov cx,13 ;filename length is 13 bytes
rep movsb ;copy filename to storage
pop cx ;restore entry value of CX
ret
copy_filename endp
;
;------------------------------------------------------------------------------
;WRITE_DIR writes one page of directory data to the directory window.
;------------------------------------------------------------------------------
write_dir proc near
mov end_flag,0 ;initialize END_FLAG
mov ax,520 ;520 bytes per directory page
mov bl,dir_page ;get page number in BL
xor bh,bh ;byte to word in BX
mul bx ;find offset into TEXT_BUFFER
mov si,ax ;transfer offset to SI
add si,text_buffer ;complete address calculation
mov dx,030Ah ;specify starting cursor position
mov cx,10 ;do 10 lines
wdir4: push cx ;save line counter
call write_line ;write one line
inc dh ;set cursor to next line
mov dl,10
pop cx ;restore line count
cmp end_flag,0 ;END_FLAG set?
jne wdir5 ;yes, then terminate
loop wdir4 ;loop until all lines are done
wdir5: ret
write_dir endp
;
;------------------------------------------------------------------------------
;WRITE_LINE writes a single line of directory text to the display.
;Entry: DH,DL - starting row and column
;------------------------------------------------------------------------------
write_line proc near
mov cx,4 ;4 entries per line
wline1: push cx ;save counter
push si ;save text address
push dx ;save cursor address
call write_string ;write one entry
pop dx ;retrieve cursor address
add dl,16 ;set cursor to next field
pop si ;retrieve text address
add si,13 ;set it for next write
pop cx ;retrieve count
cmp end_flag,0 ;END_FLAG set?
jne wline2 ;yes, then exit
loop wline1 ;loop until done
wline2: ret
write_line endp
;
;------------------------------------------------------------------------------
;WRITE_STRING writes an ASCIIZ string to the display.
;Entry: DH,DL - starting row and column
; DS:SI - string address
;------------------------------------------------------------------------------
write_string proc near
mov ah,2 ;set cursor to start position
mov bh,video_page
int 10h
mov cx,1 ;output one character at a time
write1: lodsb ;get a character
or al,al ;is it a zero?
je write3 ;yes, then exit
cmp al,255 ;is it 255?
je write2 ;yes, then set END_FLAG and exit
mov ah,10 ;print character
int 10h
mov ah,2 ;advance cursor
inc dl
int 10h
jmp write1 ;loop until done
write2: mov end_flag,1 ;set END_FLAG
write3: ret
write_string endp
;
;------------------------------------------------------------------------------
;CLEAR_WINDOW clears the contents of the directory window.
;------------------------------------------------------------------------------
clear_window proc near
mov ah,6 ;clear window with BIOS routine
mov al,0 ;specify clear function
mov cx,030Ah ;specify window coordinates
mov dx,0C45h
mov bh,text_attr ;attribute to be used
int 10h
ret
clear_window endp
;
;------------------------------------------------------------------------------
;CLEAR_INPUT_LINE clears the window input line.
;------------------------------------------------------------------------------
clear_input_line proc near
mov ah,2 ;set cursor to start of input line
mov dx,020Ah
mov bh,video_page
int 10h
mov ah,10 ;then write a string of spaces
mov al,32
mov cx,60
int 10h
ret
clear_input_line endp
;
;------------------------------------------------------------------------------
;INITIALIZE prepares the program for residency.
;------------------------------------------------------------------------------
initialize proc near
;
;Determine what type of video adapter is installed.
;
mov ah,12h ;prepare for call to int 10h
mov bl,10h ;function - request EGA info
int 10h
cmp bl,10h ;BL=10h?
je init1 ;yes, then no EGA installed
or bh,bh ;BH=0?
jne init2 ;no, then it's a monochrome system
jmp init3
init1: dec adapter ;decrement ADAPTER value
mov ah,15 ;get video mode
int 10h
cmp al,7 ;is it mode 7?
jne init3 ;no, then it's a color system
dec adapter ;set ADAPTER to 0
;
;Modify video parameter values for monochrome, then initialize the cursor.
;
init2: sub video_segment,800h ;set VIDEO_SEGMENT for monochrome
mov border_attr,70h ;change attributes for monochrome
mov text_attr,07h
mov default_cursor,0C0Dh ;set monochrome cursor definition
init3: call show_cursor ;set cursor to default mode
;
;Determine the port address of the CRT Controller and store it.
;
mov ax,40h ;point ES to BIOS data segment
mov es,ax
mov di,63h ;point DI to address word
mov dx,es:[di] ;get CRTC address
mov addr_6845,dx ;save it
;
;Get and save the address of the DOS BUSY_FLAG.
;
mov ah,34h ;function 34h
int 21h ;get address
mov dos_segment,es ;save segment
mov busy_flag,bx ;save offset
;
;Save and replace all required interrupt vectors.
;
mov ah,35h ;get interrupt 9 vector
mov al,9
int 21h
mov old9h,bx ;save it
mov old9h[2],es
mov ah,25h ;point it to KEYBOARD routine
lea dx,keyboard
int 21h
mov ah,35h ;get interrupt 1Ch vector
mov al,8 ;patched vh
int 21h
mov old1ch,bx ;save it
mov old1ch[2],es
mov ah,25h ;then point it to TIMER
lea dx,timer
int 21h
mov ah,35h ;get interrupt 13h vector
mov al,13h
int 21h
mov old13h,bx ;save it
mov old13h[2],es
mov ah,25h ;point it to BDISK
lea dx,bdisk
int 21h
mov ah,35h ;get interrupt 28h vector
mov al,28h
int 21h
mov old28h,bx ;save it
mov old28h[2],es
mov ah,25h ;point it to BACKPROC
lea dx,backproc
int 21h
;
;Terminate but remain resident in memory.
;
mov dx,offset initialize+6216 ;point DX to end of resident code
int 27h ;terminate-but-stay-resident
initialize endp
;
code ends
end begin